package cn.virens.mybatis.page;

import java.util.List;
import java.util.Map;
import java.util.function.Function;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.page.PageMethod;

import cn.hutool.core.util.ObjectUtil;
import cn.virens.common.exception.APIException;
import cn.virens.common.utils.Assert;

public class PageResultQuery implements AutoCloseable {
	private final PageParamUser param;

	private PageResultQuery(PageParamUser pageParam) {
		this.param = Assert.isNull(pageParam);
	}

	public static <R> PageResult<R> selectPage(PageParamUser param, Function<PageResultQuery, List<R>> fun) {
		try (PageResultQuery answer = new PageResultQuery(param)) {
			// 获取分页参数
			Integer pageSize = ObjectUtil.defaultIfNull(param.getPageSize(), 20);
			Integer pageNum = ObjectUtil.defaultIfNull(param.getPageNum(), 1);

			// 设置分页信息
			Page<Object> _page = PageMethod.startPage(pageNum, pageSize);
			_page.setOrderBy(ObjectUtil.defaultIfNull(param.getOrderBy(), null));
			_page.setCount(ObjectUtil.defaultIfNull(param.isCount(), true));

			PageResult<R> result = new PageResult<>();

			// 执行查询 并 获取查询结果中的分页信息
			PageInfo<R> pageInfo = PageInfo.of(fun.apply(answer));
			result.setPageSize(pageInfo.getPageSize());
			result.setPageNum(pageInfo.getPageNum());
			result.setPages(pageInfo.getPages());
			result.setTotal(pageInfo.getTotal());
			result.setSize(pageInfo.getSize());
			result.setList(pageInfo.getList());

			return result;
		}
	}

	public String getRole() throws APIException {
		return param != null ? param.getRole() : null;
	}

	public String getTenant() throws APIException {
		return param != null ? param.getTenant() : null;
	}

	public String getAccount() throws APIException {
		return param != null ? param.getAccount() : null;
	}

	public Map<String, Object> params() throws APIException {
		return param != null ? param.getParams() : null;
	}

	public Object criteriaEqual(String key) throws APIException {
		return PageParamUtil.criteriaEqual(params(), key);
	}

	public Object criteriaEqual(String key, Object def) throws APIException {
		return PageParamUtil.criteriaEqual(params(), key, def);
	}

	public String criteriaLike(String key) throws APIException {
		return PageParamUtil.criteriaLike(params(), key);
	}

	public String criteriaLike(String key, String def) throws APIException {
		return PageParamUtil.criteriaLike(params(), key, def);
	}

	public Iterable<Object> criteriaIn(String key) throws APIException {
		return PageParamUtil.criteriaIn(params(), key);
	}

	public Iterable<Object> criteriaIn(String key, Object def) throws APIException {
		return PageParamUtil.criteriaIn(params(), key, def);
	}

	@Override
	public void close() throws APIException {
		PageMethod.clearPage();
	}
}
